package api

import (
	"context"
	jwt2 "github.com/dgrijalva/jwt-go/v4"
	"github.com/gin-gonic/gin"
	"github.com/mervick/aes-everywhere/go/aes256"
	"go.uber.org/zap"
	"heightFive/Day_exam/day3/userApi/entity"
	"heightFive/Day_exam/day3/userApi/global"
	user "heightFive/Day_exam/day3/userApi/proto"
	"heightFive/Day_exam/day3/userApi/vender/jwt"
	"net/http"
	"time"
)

const PASSWORD = "password"

type User struct {
	Id       int
	Name     string
	Password string
	Email    string
	Phone    string
	Address  string
}

func Register(ctx *gin.Context) {
	registerPost := entity.RegisterPost{}
	//参数校验
	err := ctx.ShouldBind(&registerPost)
	if err != nil {
		zap.S().Error(err)
		ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	encrypted := aes256.Encrypt(registerPost.Password, PASSWORD)
	u := SqlToUser(User{
		Name:     registerPost.Name,
		Password: encrypted,
		Email:    registerPost.Email,
		Phone:    registerPost.Phone,
		Address:  registerPost.Address,
	})
	createUser, err := global.UserClient.CreateUser(context.Background(), &user.CreateUserReq{
		User: u,
	})
	if err != nil {
		return
	}

	ctx.JSON(200, gin.H{
		"code": createUser.Resp.Code,
		"msg":  createUser.Resp.Msg,
	})
}

func GetByUsername(ctx *gin.Context) {
	getInfoByName := entity.GetInfoByName{}
	if ctx.ShouldBindJSON(&getInfoByName) != nil {
		ctx.JSON(200, gin.H{
			"msg": "参数传递错误",
		})
	}
	data, err := global.UserClient.GetInfoByUsername(ctx, &user.GetInfoByUsernameReq{Username: getInfoByName.Name})
	if err != nil {
		ctx.JSON(200, gin.H{
			"msg": "用户不存在，请先注册",
		})
		return
	}
	//解析后的密码
	decrypted := aes256.Decrypt(data.User.Password, PASSWORD)
	if decrypted != getInfoByName.Password {
		ctx.JSON(200, gin.H{
			"msg": "密码错误",
		})
		return
	}
	//jwt token生成
	token, err := jwt.CreateToken(&jwt.MyCustomClaims{
		//存储用户ID
		UserId: data.User.Id,
		//过期时间
		StandardClaims: jwt2.StandardClaims{
			ExpiresAt: jwt2.NewTime(float64(time.Now().Unix() + 86400)),
		},
	})
	ctx.JSON(200, gin.H{
		"code":  http.StatusOK,
		"msg":   "success",
		"token": token,
	})
}

func SqlToUser(user2 User) *user.UserInfo {
	return &user.UserInfo{
		Id:       int64(user2.Id),
		Name:     user2.Name,
		Password: user2.Password,
		Email:    user2.Email,
		Phone:    user2.Phone,
		Address:  user2.Address,
	}
}

func UserToSql(info *user.UserInfo) User {
	return User{
		Name:    info.Name,
		Email:   info.Email,
		Phone:   info.Phone,
		Address: info.Address,
	}
}
